<!DOCTYPE html>
<html>

<head>
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
      background: #fff;
      background-position: center 0;
      background-size: 100% 100%;
      background-repeat: no-repeat;
      position: relative;
    }


    #timeShow {
      width: 100vw;
      height: 100vh;
      overflow: hidden;
      border: 1px solid #000;
      position: fixed;
      bottom: 0px;
      /* background: #000; */
    }
  </style>
</head>

<body>
  <div id='timeShow'></div>

</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r106/three.min.js"></script>
<script type="text/javascript" src="https://lib.baomitu.com/stats.js/16/Stats.min.js"></script>

<script src="https://wow.techbrood.com/uploads/160101/TrackballControls.js"></script>

<script>

  // 初始化性能插件
  const stats = new Stats()
  stats.showPanel(0) // 0: fps, 1: ms, 2: mb, 3+: custom
  document.body.appendChild(stats.dom)

  // 变量定义
  let container
  let camera, scene, renderer
  let count = 0
  let mouseX2 = 0
  let mouseY2 = 0
  let windowHalfX = window.innerWidth / 2
  let windowHalfY = window.innerHeight / 2

  let cameraTarget
  let control
  let numberGroup = new THREE.Group()
  let number2Group = new THREE.Group()


  // control functions
  const onWindowResize = () => {
    windowHalfX = container.innerWidth / 2
    windowHalfY = container.innerHeight / 2
    camera.aspect = container.clientWidth / container.clientHeight
    camera.updateProjectionMatrix()
    renderer.setSize(container.clientWidth, container.clientHeight)
  }



  const init = () => {
    container = document.getElementById("timeShow")

    camera = new THREE.PerspectiveCamera(30, container.clientWidth / container.clientHeight, 1, 1500)
    camera.position.set(10, 60, 110)
    // cameraTarget = new THREE.Vector3(15, 15, 0);

    scene = new THREE.Scene()



    // 创建平面。
    const planeGeometry = new THREE.PlaneGeometry(100, 100, 1, 1)
    // 设置平面的材质
    const planeMaterial = new THREE.MeshLambertMaterial({
      'color': 0xffffff
    })
    // 赋值到Mesh
    const plane = new THREE.Mesh(planeGeometry, planeMaterial)
    // 设置平面位置和旋转
    plane.rotation.x = -0.5 * Math.PI
    plane.position.set(0, 0, 0)
    // 设置地面为投影面
    plane.receiveShadow = true
    // 将平面添加到场景中
    scene.add(plane)


    // 坐标
    let axisHelper = new THREE.AxisHelper(30);
    scene.add(axisHelper);

    createTime(numberGroup,[-10,15,15])
    createTime(number2Group,[15,15,15])


    //环境光    环境光颜色与网格模型的颜色进行RGB进行乘法运算
    let ambient = new THREE.AmbientLight(0x444444);
    scene.add(ambient);


    //第一个参数 Hex:光的颜色 第二个参数 Intensity：光源的强度，默认是1.0，如果为0.5，则强度是一半，意思是颜色会淡一些
    //第三个参数 Distance：光线的强度，从最大值衰减到0，需要的距离。 默认为0，表示光不衰减，如果非0，则表示从光源的位置到Distance的距离，光都在线性衰减。到离光源距离Distance时，光源强度为0.
    
    // let light = new THREE.DirectionalLight(0xFF0000, 1, 0);
    // // 位置不同，方向光作用于物体的面也不同，看到的物体各个面的颜色也不一样
    // light.position.set(0, 0, 1);//光源的向量，即光源的位置
    // scene.add(light);//追加光源到场景


    //点光源
    let point = new THREE.PointLight(0xffffff);
    point.position.set(0, 60, -30);
    point.castShadow = true;
    point.shadow.camera.near = 2; // 照射的最近距离
    point.shadow.camera.far = 81; // 照射的最远距离
    point.shadow.mapSize.width = 1024;
    point.shadow.mapSize.height = 1024;
    point.shadow.radius = 15 // 模糊阴影

    const pointCameraHelper = new THREE.CameraHelper(point.shadow.camera)
    // scene.add(pointCameraHelper)
    // scene.add(point);

    // 平行光
    // let directionalLight = new THREE.DirectionalLight(0xffffff); 
    // directionalLight.position.set(40, 70, 100);
    // directionalLight.castShadow = true;
    // directionalLight.shadow.mapSize.width = 1024;
    // directionalLight.shadow.mapSize.height = 1024;
    // console.log(directionalLight);
    // directionalLight.target = numberGroup
    // directionalLight.shadow.radius = 50 // 模糊阴影

    // const directionalLightCameraHelper = new THREE.CameraHelper(directionalLight.shadow.camera)
    // scene.add(directionalLightCameraHelper)
    
    // scene.add(directionalLight);

    // 聚光灯    0xffffff,0.4,10,Math.PI*0.3
    const spotLight = new THREE.SpotLight(0xffffff,1)
    spotLight.castShadow = true
    spotLight.position.set(50,80,120)


    spotLight.shadow.mapSize.width = 5000
    spotLight.shadow.mapSize.height = 5000
    spotLight.shadow.camera.near = 100
    spotLight.shadow.camera.far = 200
    // spotLight.shadow.radius = 10 // 模糊阴影

    spotLight.target = numberGroup // 照射目标
    // 如果要使聚光灯看向某处记得把target添加场景中
    scene.add(spotLight.target)
    scene.add(spotLight)



    const spotLightCameraHelper = new THREE.CameraHelper(spotLight.shadow.camera)
    scene.add(spotLightCameraHelper)

    // const spotLight = new THREE.SpotLight(0xff0000, 0.5);
    // spotLight.angle = Math.PI / 5;
    // spotLight.penumbra = 0.2;
    // point.position.set(40, 50, 70);
    // spotLight.castShadow = true;
    // spotLight.shadow.camera.near = 3;
    // spotLight.shadow.camera.far = 100;
    // spotLight.shadow.mapSize.width = 1024;
    // spotLight.shadow.mapSize.height = 1024;
    // scene.add(spotLight);

    // const spotLightCameraHelper = new THREE.CameraHelper(spotLight.shadow.camera)
    // scene.add(spotLightCameraHelper)



    renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
    // 设置透明度
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap

    renderer.setClearAlpha(0)
    renderer.setSize(container.clientWidth, container.clientHeight)
    container.appendChild(renderer.domElement)


    clock = new THREE.Clock() // 时钟
    control = new THREE.TrackballControls(camera)
    control.minDistance = 20; // 最小视角
    control.maxDistance = 800;// 最大视角 Infinity 无穷大

    window.addEventListener('resize', onWindowResize, false);

  }


  const createTime = (group,position) => {

    // 材质
    // const material = new THREE.SpriteMaterial({
    const material = new THREE.MeshPhongMaterial({
      // color: '#000000',
      // depthWrite: false,
      // map: new THREE.CanvasTexture(sprite),
      // opacity: 0.7,
      // blending: THREE.AdditiveBlending,
      side: THREE.DoubleSide, // 双面可见
      transparent: true,
      color: 'red',
      specular: 0x4488ee,
      shininess: 12
    })

    let list = [
      { x: 0, y: 0, z: 0, direction: 'level' },
      { x: 0, y: 10, z: 0, direction: 'vertical' },
      { x: 0, y: 10, z: 0, direction: 'level' },
      { x: 10, y: 10, z: 0, direction: 'vertical' },
      { x: 10, y: -10, z: 0, direction: 'vertical' },
      { x: 0, y: -10, z: 0, direction: 'level' },
      { x: 0, y: -10, z: 0, direction: 'vertical' },
    ]
    let geometry = new THREE.BoxGeometry(2, 2, 2);

    for (let i = 0; i < 7; i++) { // 七条线
      let line = new THREE.Group()
      for (let j = 0; j <= 5; j++) { // 每条线六个点构成

        let geometryClone = geometry.clone()
        let materialClone = material.clone()
        let trajectory = new THREE.Mesh(geometryClone, materialClone);
        trajectory.castShadow = true;
        // 每个点间隔1
        const { x, y, z, direction } = list[i]
        let dir = direction === 'level'
        trajectory.position.x = dir ? x < 0 ? j * 2 + x : j * 2 + x + (-x) : x
        trajectory.position.y = !dir ? y < 0 ? j * 2 + y : j * 2 + y + (-y) : y
        trajectory.position.z = z

        line.add(trajectory)
        trajectory = null
      }
      line.name = i
      group.add(line)
    }

    group.position.set(...position)
    scene.add(group)


    console.log(group);
  }




  const animate = () => {
    stats.begin()
    stats.end()
    requestAnimationFrame(animate)
    render()
  }


  let n = 2
  setInterval(() => {
    n++
    n = n <= 9 ? n : 0
  }, 1000);


  let n2 = 2
  setInterval(() => {
    n2++
    n2 = n2 <= 9 ? n2 : 0
  }, 100);

  // show line data
  let digitalDocking = [
    [1, 2, 3, 4, 5, 6],
    [3, 4],
    [0, 2, 3, 5, 6],
    [0, 2, 3, 4, 5],
    [0, 1, 3, 4],
    [0, 1, 2, 4, 5],
    [0, 1, 2, 4, 5, 6],
    [2, 3, 4],
    [0, 1, 2, 3, 4, 5, 6],
    [0, 1, 2, 3, 4, 5]
  ]

  const render = () => {

    // camera.position.x += (mouseX2 * 0.1 - camera.position.x) * 0.05

    // camera.lookAt(cameraTarget) // 镜头追踪

    let delta = clock.getDelta()
    control.update(delta)


    numberGroup.children.forEach((line, idx) => {


      if (!digitalDocking[n].includes(idx)) {
        // hidden line

        // console.log(idx);
        // console.log(line);
        line.children.forEach(i => {
          let opacity = i.material.opacity
          i.material.opacity = opacity > 0 ? opacity - 0.07 : 0
          if (i.material.opacity === 0) line.visible = false
        })

      } else {
        // show line
        line.children.forEach(i => {
          line.visible = true
          let opacity = i.material.opacity
          i.material.opacity =  opacity < 1 ? opacity + 0.07 : 1

        })
      }
    })

    number2Group.children.forEach((line, idx) => {


      if (!digitalDocking[n2].includes(idx)) {
        // hidden line

        // console.log(idx);
        // console.log(line);
        line.children.forEach(i => {
          let opacity = i.material.opacity
          i.material.opacity = 0
          if (i.material.opacity === 0) line.visible = false
        })

      } else {
        // show line
        line.children.forEach(i => {
          line.visible = true
          let opacity = i.material.opacity
          i.material.opacity =  1

        })
      }
    })

    renderer.render(scene, camera)
    // count += 0.1
  }

  // 初始化
  init()
  animate()


</script>

</html>